import QtQuick 2.12
import QtQuick.Controls 2.12

/**
 * 离线地图查看器（基于Loader组件缓存）
 * 基于方案四技术文档实现
 * 支持加载大尺寸地图图片（0.5G - 2G）
 * 状态通过组件缓存自动保持（组件不销毁）
 */
Rectangle {
    id: offlineMapViewer
    color: "#f0f0f0"

    // 配置属性
    property string imagePath: "file:///D:/360/yunshu/text/11/qmlcreator/gis/10101514.png"  // 地图图片路径
    property real currentScale: 1.0           // 当前缩放比例
    property real minScale: 0.1               // 最小缩放
    property real maxScale: 5.0               // 最大缩放
    
    // 固定参考尺寸机制 - 解决缩放导致路径偏移问题
    property real fixedReferenceScale: 1.0   // 固定参考缩放比例，用于路径计算和坐标转换
    property bool useFixedReference: true    // 是否使用固定参考尺寸（仅影响工作区地图模式）
    
    // 状态属性
    property bool imageLoaded: false          // 是否已加载
    property bool imageLoading: false         // 是否正在加载
    property bool forceReload: false          // 强制重新加载标记
    
    // 地图范围（经纬度）- 与10101514.txt对应
    property real minLon: 109.223327637
    property real maxLon: 109.256973267
    property real minLat: 23.706151920
    property real maxLat: 23.743240298
    
    // 暴露数据模型给外部访问
    property alias fieldPointsModel: fieldPointsModel
    property alias pathPointsModel: pathPointsModel
    property alias robotPositionsModel: robotPositionsModel
    
    // 信号定义
    signal mapReady()
    signal locationChanged(real lon, real lat)
    signal mapClicked(real lon, real lat)
    signal pathPointAdded(real lon, real lat, int index)
    signal pathPointRemoved(int index)
    signal pathChanged()
    signal scaleChanged(real scale)
    
    // 标记点模型
    ListModel {
        id: markersModel
    }
    
    // 路径点模型
    ListModel {
        id: pathPointsModel
    }
    
    // 机器人位置模型
    ListModel {
        id: robotPositionsModel
    }
    
    // 农田规划点模型
    ListModel {
        id: fieldPointsModel
    }
    
    // 路径规划相关属性
    property bool pathEditMode: false          // 路径编辑模式
    property bool fieldPlanMode: false         // 农田规划模式
    property bool fieldPlanSaved: false        // 农田规划是否已保存
    property bool showRobotPosition: true     // 显示机器人位置
    property real pathLineWidth: 3.0          // 路径线宽度
    property color pathLineColor: "#e74c3c"   // 路径线颜色
    property color pathPointColor: "#3498db"  // 路径点颜色
    property color robotPositionColor: "#27ae60" // 机器人位置颜色
    property color fieldAreaColor: "#ff9800"    // 农田区域颜色
    property color fieldBorderColor: "#f57c00"  // 农田边界颜色
    property color fieldBorderColorSaved: "#4caf50"  // 已保存农田边界颜色
    
    Component.onCompleted: {
        console.log("✅ 离线地图查看器初始化（使用组件缓存，状态自动保持）")
        console.log("地图路径:", imagePath)
        
        // 初始化固定参考尺寸机制
        setFixedReferenceScale(1.0)  // 使用1.0作为固定参考缩放比例
        setUseFixedReference(true)    // 启用固定参考尺寸机制
        
        // 自动加载地图
        loadTimer.start()
    }
    
    Component.onDestruction: {
        console.log("⚠️ 离线地图查看器销毁（如果看到这条消息，说明缓存失败）")
    }
    
    // 延迟加载定时器
    Timer {
        id: loadTimer
        interval: 200
        running: false
        repeat: false
        onTriggered: {
            console.log("开始加载地图...")
            loadMap()
        }
    }
    
    // 主容器（去掉Column布局，直接使用Rectangle）
    Item {
        anchors.fill: parent
        
        // 隐藏控制面板（由GISPage控制）
        Rectangle {
            id: controlPanel
            width: parent.width
            height: 0  // 高度设为0，隐藏控制面板
            visible: false
            color: "white"
            border.color: "#ddd"
            border.width: 1
            z: 100
            
            Row {
                anchors.fill: parent
                anchors.margins: 10
                spacing: 10
                
                // 加载按钮
                Button {
                    text: imageLoaded ? "已加载" : "加载地图"
                    width: 100
                    height: 40
                    enabled: !imageLoading && !imageLoaded
                    
                    background: Rectangle {
                        color: parent.enabled ? (parent.pressed ? "#27ae60" : "#2ecc71") : "#95a5a6"
                        radius: 4
                    }
                    
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 12
                        font.bold: true
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                    
                    onClicked: {
                        loadMap()
                    }
                }
                
                // 状态显示
                Rectangle {
                    width: 150
                    height: 40
                    color: imageLoading ? "#f39c12" : (imageLoaded ? "#27ae60" : "#95a5a6")
                    radius: 4
                    
                    Row {
                        anchors.centerIn: parent
                        spacing: 8
                        
                        Rectangle {
                            width: 8
                            height: 8
                            radius: 4
                            color: "white"
                            anchors.verticalCenter: parent.verticalCenter
                            
                            SequentialAnimation on opacity {
                                running: imageLoading
                                loops: Animation.Infinite
                                NumberAnimation { from: 1.0; to: 0.3; duration: 500 }
                                NumberAnimation { from: 0.3; to: 1.0; duration: 500 }
                            }
                        }
                        
                        Text {
                            text: imageLoading ? "加载中..." : (imageLoaded ? "已就绪" : "未加载")
                            color: "white"
                            font.pixelSize: 12
                            font.bold: true
                            anchors.verticalCenter: parent.verticalCenter
                        }
                    }
                }
                
                // 分隔线
                Rectangle {
                    width: 1
                    height: parent.height - 20
                    color: "#ddd"
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                // 缩放控制
                Label {
                    text: "缩放:"
                    font.pixelSize: 12
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Button {
                    text: "−−"
                    width: 40
                    height: 30
                    enabled: imageLoaded
                    onClicked: zoomOut(0.5)
                }
                
                Button {
                    text: "−"
                    width: 40
                    height: 30
                    enabled: imageLoaded
                    onClicked: zoomOut(0.1)
                }
                
                Label {
                    text: (currentScale * 100).toFixed(0) + "%"
                    font.pixelSize: 13
                    font.bold: true
                    width: 60
                    horizontalAlignment: Text.AlignHCenter
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Button {
                    text: "+"
                    width: 40
                    height: 30
                    enabled: imageLoaded
                    onClicked: zoomIn(0.1)
                }
                
                Button {
                    text: "++"
                    width: 40
                    height: 30
                    enabled: imageLoaded
                    onClicked: zoomIn(0.5)
                }
                
                // 分隔线
                Rectangle {
                    width: 1
                    height: parent.height - 20
                    color: "#ddd"
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Button {
                    text: "适应窗口"
                    width: 80
                    height: 30
                    enabled: imageLoaded
                    onClicked: autoFitToWindow()
                }
                
                Button {
                    text: "100%"
                    width: 60
                    height: 30
                    enabled: imageLoaded
                    onClicked: currentScale = 1.0
                }
                
                Button {
                    text: "重置"
                    width: 60
                    height: 30
                    enabled: imageLoaded
                    
                    background: Rectangle {
                        color: parent.enabled ? "#e74c3c" : "#95a5a6"
                        radius: 4
                    }
                    
                    contentItem: Text {
                        text: parent.text
                        color: "white"
                        font.pixelSize: 11
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                    
                    onClicked: resetView()
                }
            }
        }
        
        // 图片显示区域（占满整个空间）
        Rectangle {
            anchors.fill: parent
            color: "#2c3e50"
            clip: true
            
            // 加载前提示
            Column {
                anchors.centerIn: parent
                spacing: 20
                visible: !imageLoading && !imageLoaded
                
                Rectangle {
                    width: 80
                    height: 80
                    radius: 40
                    color: "#34495e"
                    anchors.horizontalCenter: parent.horizontalCenter
                    
                    Text {
                        anchors.centerIn: parent
                        text: "🗺️"
                        font.pixelSize: 40
                    }
                }
                
                Label {
                    text: "离线地图查看器"
                    font.pixelSize: 20
                    font.bold: true
                    color: "white"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                
                Label {
                    text: "点击\"加载地图\"开始查看"
                    font.pixelSize: 14
                    color: "#bdc3c7"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                
                Label {
                    text: "图片大小: 约0.8GB"
                    font.pixelSize: 12
                    color: "#7f8c8d"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
            }
            
            // 加载中动画
            BusyIndicator {
                anchors.centerIn: parent
                running: imageLoading
                visible: imageLoading
                width: 80
                height: 80
            }
            
            Column {
                anchors.centerIn: parent
                spacing: 15
                visible: imageLoading
                
                Label {
                    text: "正在加载地图..."
                    font.pixelSize: 16
                    font.bold: true
                    color: "white"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                
                Label {
                    text: "这可能需要10-30秒，请耐心等待"
                    font.pixelSize: 12
                    color: "#bdc3c7"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
            }
            
            // Flickable滚动容器
            Flickable {
                id: flickable
                anchors.fill: parent
                clip: true
                visible: imageLoaded
                
                contentWidth: bigImage.sourceSize.width * currentScale
                contentHeight: bigImage.sourceSize.height * currentScale
                
                ScrollBar.horizontal: ScrollBar { 
                    policy: ScrollBar.AlwaysOn 
                    visible: imageLoaded
                }
                ScrollBar.vertical: ScrollBar { 
                    policy: ScrollBar.AlwaysOn 
                    visible: imageLoaded
                }
                
                // 地图图片
                Image {
                    id: bigImage
                    source: ""  // 初始为空
                    cache: true  // 启用缓存以提高性能
                    asynchronous: true  // 异步加载，不阻塞UI
                    smooth: false  // 关闭平滑渲染以提高性能
                    
                    // 移除尺寸限制以显示完整地图
                    
                    width: sourceSize.width
                    height: sourceSize.height
                    
                    transform: Scale {
                        xScale: currentScale
                        yScale: currentScale
                        origin.x: 0
                        origin.y: 0
                    }
                    
                    onWidthChanged: {
                        // 当图片宽度改变时，更新Flickable的内容大小（使用sourceSize）
                        if (bigImage.sourceSize.width > 0) {
                            flickable.contentWidth = bigImage.sourceSize.width * currentScale
                        }
                    }
                    
                    onHeightChanged: {
                        // 当图片高度改变时，更新Flickable的内容大小（使用sourceSize）
                        if (bigImage.sourceSize.height > 0) {
                            flickable.contentHeight = bigImage.sourceSize.height * currentScale
                        }
                    }
                    
                    onStatusChanged: {
                        console.log("图片状态变化:", status)
                        if (status === Image.Loading) {
                            imageLoading = true
                            imageLoaded = false
                            console.log("图片开始加载...")
                        } else if (status === Image.Ready) {
                            imageLoading = false
                            imageLoaded = true
                            console.log("✅ 地图图片加载成功!")
                            console.log("图片尺寸:", sourceSize.width, "×", sourceSize.height)
                            
                            // 首次加载时自动适应窗口
                            if (forceReload || currentScale === 1.0) {
                                autoFitToWindow()
                                forceReload = false
                            }
                            // 否则保持当前缩放和位置（组件缓存自动保持）
                            
                            mapReady()
                        } else if (status === Image.Error) {
                            imageLoading = false
                            imageLoaded = false
                            console.error("❌ 地图加载失败! source:", source)
                            console.error("请检查文件路径是否正确:", imagePath)
                        } else if (status === Image.Null) {
                            console.log("图片源为空")
                        }
                    }
                }
                
                // 路径绘制Canvas
                Canvas {
                    id: pathCanvas
                    anchors.fill: parent
                    visible: imageLoaded
                    z: 5
                    
                    onPaint: {
                        var ctx = getContext("2d")
                        ctx.clearRect(0, 0, width, height)
                        
                        var referenceScale = useFixedReference ? fixedReferenceScale : currentScale
                        console.log("Canvas重绘 - 当前缩放:", currentScale, "参考缩放:", referenceScale, "偏移:", flickable.contentX, flickable.contentY)
                        
                        // 绘制路径线
                        if (pathPointsModel.count > 1) {
                            ctx.strokeStyle = pathLineColor
                            ctx.lineWidth = pathLineWidth
                            ctx.lineCap = "round"
                            ctx.lineJoin = "round"
                            
                            ctx.beginPath()
                            for (var i = 0; i < pathPointsModel.count; i++) {
                                var point = pathPointsModel.get(i)
                                var screenPos = lonLatToScreenPosition(point.lon, point.lat)
                                
                                if (i === 0) {
                                    ctx.moveTo(screenPos.x, screenPos.y)
                                } else {
                                    ctx.lineTo(screenPos.x, screenPos.y)
                                }
                            }
                            ctx.stroke()
                        }
                        
                        // 绘制路径点
                        ctx.fillStyle = pathPointColor
                        for (var j = 0; j < pathPointsModel.count; j++) {
                            var pathPoint = pathPointsModel.get(j)
                            var screenPos = lonLatToScreenPosition(pathPoint.lon, pathPoint.lat)
                            
                            ctx.beginPath()
                            ctx.arc(screenPos.x, screenPos.y, 8, 0, 2 * Math.PI)
                            ctx.fill()
                            
                            // 路径点边框
                            ctx.strokeStyle = "white"
                            ctx.lineWidth = 2
                            ctx.stroke()
                            
                            // 路径点序号
                            ctx.fillStyle = "white"
                            ctx.font = "bold 10px Arial"
                            ctx.textAlign = "center"
                            ctx.textBaseline = "middle"
                            ctx.fillText((j + 1).toString(), screenPos.x, screenPos.y)
                            ctx.fillStyle = pathPointColor
                        }
                        
                        // 绘制机器人位置
                        if (showRobotPosition && robotPositionsModel.count > 0) {
                            console.log("绘制机器人位置，数量:", robotPositionsModel.count)
                            for (var k = 0; k < robotPositionsModel.count; k++) {
                                var robot = robotPositionsModel.get(k)
                                var robotScreenPos = lonLatToScreenPosition(robot.lon, robot.lat)
                                
                                console.log("机器人", k, "屏幕坐标:", robotScreenPos.x, robotScreenPos.y)
                                
                                // 机器人位置圆圈
                                ctx.fillStyle = robotPositionColor
                                ctx.beginPath()
                                ctx.arc(robotScreenPos.x, robotScreenPos.y, 12, 0, 2 * Math.PI)
                                ctx.fill()
                                
                                // 机器人位置边框
                                ctx.strokeStyle = "white"
                                ctx.lineWidth = 3
                                ctx.stroke()
                                
                                // 机器人标签背景
                                ctx.fillStyle = "rgba(39, 174, 96, 0.9)"
                                ctx.fillRect(robotScreenPos.x - 30, robotScreenPos.y - 30, 60, 20)
                                
                                // 机器人SN文字
                                ctx.fillStyle = "white"
                                ctx.font = "bold 10px Arial"
                                ctx.textAlign = "center"
                                ctx.textBaseline = "middle"
                                ctx.fillText(robot.sn, robotScreenPos.x, robotScreenPos.y - 20)
                            }
                        }
                        
                        // 绘制农田规划区域
                        if (fieldPointsModel.count > 0) {
                            // 绘制填充多边形（只在未保存且点数>=3时显示）
                            if (!fieldPlanSaved && fieldPointsModel.count >= 3) {
                                ctx.fillStyle = Qt.rgba(fieldAreaColor.r, fieldAreaColor.g, fieldAreaColor.b, 0.3)
                                ctx.beginPath()
                                
                                for (var f = 0; f < fieldPointsModel.count; f++) {
                                    var fieldPoint = fieldPointsModel.get(f)
                                    var fieldScreenPos = lonLatToScreenPosition(fieldPoint.lon, fieldPoint.lat)
                                    
                                    if (f === 0) {
                                        ctx.moveTo(fieldScreenPos.x, fieldScreenPos.y)
                                    } else {
                                        ctx.lineTo(fieldScreenPos.x, fieldScreenPos.y)
                                    }
                                }
                                ctx.closePath()
                                ctx.fill()
                            }
                            
                            // 绘制边界线（仅在点数>=2时显示连线）
                            if (fieldPointsModel.count >= 2) {
                                ctx.strokeStyle = fieldPlanSaved ? fieldBorderColorSaved : fieldBorderColor
                                ctx.lineWidth = fieldPlanSaved ? 2 : 3
                                ctx.setLineDash(fieldPlanSaved ? [5, 5] : [])
                                ctx.beginPath()
                                
                                for (var f2 = 0; f2 < fieldPointsModel.count; f2++) {
                                    var fieldPoint2 = fieldPointsModel.get(f2)
                                    var fieldScreenPos2 = lonLatToScreenPosition(fieldPoint2.lon, fieldPoint2.lat)
                                    
                                    if (f2 === 0) {
                                        ctx.moveTo(fieldScreenPos2.x, fieldScreenPos2.y)
                                    } else {
                                        ctx.lineTo(fieldScreenPos2.x, fieldScreenPos2.y)
                                    }
                                }
                                
                                if (fieldPointsModel.count >= 3) {
                                    ctx.closePath()
                                }
                                ctx.stroke()
                                ctx.setLineDash([])
                            }
                            
                            // 绘制农田规划点
                            for (var f3 = 0; f3 < fieldPointsModel.count; f3++) {
                                var fieldPoint3 = fieldPointsModel.get(f3)
                                var fieldScreenPos3 = lonLatToScreenPosition(fieldPoint3.lon, fieldPoint3.lat)
                                
                                // 外圈
                                ctx.fillStyle = fieldPlanSaved ? fieldBorderColorSaved : fieldBorderColor
                                ctx.strokeStyle = "white"
                                ctx.lineWidth = 3
                                ctx.beginPath()
                                ctx.arc(fieldScreenPos3.x, fieldScreenPos3.y, 12, 0, 2 * Math.PI)
                                ctx.fill()
                                ctx.stroke()
                                
                                // 内圈
                                ctx.fillStyle = "white"
                                ctx.beginPath()
                                ctx.arc(fieldScreenPos3.x, fieldScreenPos3.y, 8, 0, 2 * Math.PI)
                                ctx.fill()
                                
                                // 序号
                                ctx.fillStyle = fieldPlanSaved ? fieldBorderColorSaved : fieldBorderColor
                                ctx.font = "bold 12px Arial"
                                ctx.textAlign = "center"
                                ctx.textBaseline = "middle"
                                ctx.fillText((f3 + 1).toString(), fieldScreenPos3.x, fieldScreenPos3.y)
                            }
                        }
                    }
                    
                    // 监听路径和机器人位置变化，重新绘制
                    Connections {
                        target: pathPointsModel
                        onCountChanged: {
                            console.log("路径点数量变化:", pathPointsModel.count)
                            if (pathCanvas) {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                    
                    Connections {
                        target: robotPositionsModel
                        onCountChanged: {
                            console.log("机器人位置数量变化:", robotPositionsModel.count)
                            if (pathCanvas) {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                    
                    Connections {
                        target: fieldPointsModel
                        onCountChanged: {
                            console.log("农田规划点数量变化:", fieldPointsModel.count)
                            if (pathCanvas) {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                    
                    Connections {
                        target: offlineMapViewer
                        onFieldPlanSavedChanged: {
                            if (pathCanvas) {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                    
                    // 监听缩放变化，重新绘制
                    Connections {
                        target: offlineMapViewer
                        onCurrentScaleChanged: {
                            console.log("缩放变化触发Canvas重绘")
                            if (pathCanvas && typeof pathCanvas.requestPaint === "function") {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                    
                    // 监听Flickable滚动变化，重新绘制
                    Connections {
                        target: flickable
                        onContentXChanged: {
                            if (pathCanvas && typeof pathCanvas.requestPaint === "function") {
                                pathCanvas.requestPaint()
                            }
                        }
                        onContentYChanged: {
                            if (pathCanvas && typeof pathCanvas.requestPaint === "function") {
                                pathCanvas.requestPaint()
                            }
                        }
                    }
                }
                
                // 标记点容器
                Repeater {
                    model: markersModel
                    
                    Item {
                        x: lonToPixelX(model.lon) * currentScale - 12
                        y: latToPixelY(model.lat) * currentScale - 24
                        width: 24
                        height: 24
                        visible: imageLoaded
                        z: 6
                        
                        Rectangle {
                            width: 24
                            height: 24
                            color: model.color || "#e74c3c"
                            border.color: "white"
                            border.width: 2
                            radius: 12
                            
                            Text {
                                anchors.centerIn: parent
                                text: "📍"
                                font.pixelSize: 14
                            }
                        }
                        
                        // 标记点标题
                        Rectangle {
                            anchors.top: parent.bottom
                            anchors.horizontalCenter: parent.horizontalCenter
                            anchors.topMargin: 4
                            width: markerTitle.width + 8
                            height: markerTitle.height + 4
                            color: "white"
                            border.color: "#ddd"
                            border.width: 1
                            radius: 2
                            visible: model.title !== ""
                            
                            Text {
                                id: markerTitle
                                anchors.centerIn: parent
                                text: model.title || ""
                                font.pixelSize: 10
                                color: "#2c3e50"
                            }
                        }
                    }
                }
                
                // 滚轮缩放和路径点编辑
                MouseArea {
                    anchors.fill: parent
                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    
                    onClicked: {
                        if (imageLoaded) {
                            console.log("地图点击 - 鼠标位置:", mouse.x, mouse.y)
                            console.log("地图点击 - 内容偏移:", flickable.contentX, flickable.contentY)
                            console.log("地图点击 - 缩放比例:", currentScale)
                            
                            // 使用统一的坐标转换函数
                            var coords = screenPositionToLonLat(mouse.x, mouse.y)
                            var lon = coords.lon
                            var lat = coords.lat
                            
                            console.log("地图点击 - 经纬度:", lon.toFixed(8), lat.toFixed(8))
                            
                            // 处理农田规划模式
                            if (fieldPlanMode && mouse.button === Qt.LeftButton) {
                                addFieldPoint(lon, lat)
                            }
                            // 处理路径编辑模式
                            else if (pathEditMode && mouse.button === Qt.LeftButton) {
                                addPathPoint(lon, lat)
                            } else if (pathEditMode && mouse.button === Qt.RightButton) {
                                // 右键删除最近的路径点
                                removeNearestPathPoint(lon, lat)
                            } else {
                                // 普通点击事件
                                mapClicked(lon, lat)
                            }
                        }
                    }
                    
                    onWheel: {
                        if (!imageLoaded) return
                        
                        var oldScale = currentScale
                        
                        // 计算新缩放比例
                        if (wheel.angleDelta.y > 0) {
                            currentScale = Math.min(maxScale, currentScale * 1.1)
                        } else {
                            currentScale = Math.max(minScale, currentScale / 1.1)
                        }
                        
                        // 更新Flickable内容大小（使用sourceSize）
                        flickable.contentWidth = bigImage.sourceSize.width * currentScale
                        flickable.contentHeight = bigImage.sourceSize.height * currentScale
                        
                        // 调整滚动位置，保持鼠标位置为缩放中心
                        var scaleRatio = currentScale / oldScale
                        flickable.contentX = wheel.x + (flickable.contentX - wheel.x) * scaleRatio
                        flickable.contentY = wheel.y + (flickable.contentY - wheel.y) * scaleRatio
                        clampFlickableOffsets()
                        
                        wheel.accepted = true
                        
                        updateCenterLocation()
                    }
                }
                
                onContentXChanged: updateCenterLocation()
                onContentYChanged: updateCenterLocation()
            }
            
            // 错误提示
            Column {
                anchors.centerIn: parent
                spacing: 20
                visible: !imageLoading && !imageLoaded && bigImage.source !== ""
                
                Rectangle {
                    width: 80
                    height: 80
                    radius: 40
                    color: "#e74c3c"
                    anchors.horizontalCenter: parent.horizontalCenter
                    
                    Text {
                        anchors.centerIn: parent
                        text: "❌"
                        font.pixelSize: 40
                    }
                }
                
                Label {
                    text: "地图加载失败"
                    font.pixelSize: 18
                    font.bold: true
                    color: "white"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                
                Label {
                    text: "请检查文件路径是否正确"
                    font.pixelSize: 12
                    color: "#bdc3c7"
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                
                Label {
                    text: imagePath
                    font.pixelSize: 10
                    color: "#7f8c8d"
                    anchors.horizontalCenter: parent.horizontalCenter
                    elide: Text.ElideMiddle
                    width: 400
                }
            }
        }
        
        // 状态栏（隐藏，由GISPage显示状态）
        Rectangle {
            id: statusBar
            width: parent.width
            height: 0  // 高度设为0，隐藏状态栏
            visible: false
            color: "#34495e"
            border.color: "#2c3e50"
            border.width: 1
            
            Row {
                anchors.fill: parent
                anchors.margins: 8
                spacing: 20
                
                Label {
                    text: "图片尺寸: " + (imageLoaded ? bigImage.sourceSize.width + "×" + bigImage.sourceSize.height : "−")
                    color: "#ecf0f1"
                    font.pixelSize: 11
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Label {
                    text: "缩放: " + (currentScale * 100).toFixed(0) + "%"
                    color: "#ecf0f1"
                    font.pixelSize: 11
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Label {
                    text: "位置: X=" + Math.round(flickable.contentX) + " Y=" + Math.round(flickable.contentY)
                    color: "#ecf0f1"
                    font.pixelSize: 11
                    anchors.verticalCenter: parent.verticalCenter
                    visible: imageLoaded
                }
                
                Rectangle {
                    width: 1
                    height: parent.height - 10
                    color: "#7f8c8d"
                    anchors.verticalCenter: parent.verticalCenter
                }
                
                Label {
                    text: "快捷键: 滚轮=缩放 | 拖拽=移动 | +/−=缩放"
                    color: "#bdc3c7"
                    font.pixelSize: 10
                    anchors.verticalCenter: parent.verticalCenter
                }
            }
        }
    }
    
    // ==================== 统一坐标转换函数 ====================
    
    // 经度转像素X坐标（原始图片坐标系）
    function lonToPixelX(lon) {
        if (!imageLoaded || bigImage.sourceSize.width === 0) return 0
        var ratio = (lon - minLon) / (maxLon - minLon)
        return ratio * bigImage.sourceSize.width
    }
    
    // 纬度转像素Y坐标（原始图片坐标系，Y轴反转）
    function latToPixelY(lat) {
        if (!imageLoaded || bigImage.sourceSize.height === 0) return 0
        var ratio = (maxLat - lat) / (maxLat - minLat)
        return ratio * bigImage.sourceSize.height
    }
    
    // 像素X坐标转经度
    function pixelXToLon(px) {
        if (!imageLoaded || bigImage.sourceSize.width === 0) return 0
        var ratio = px / bigImage.sourceSize.width
        return minLon + ratio * (maxLon - minLon)
    }
    
    // 像素Y坐标转纬度
    function pixelYToLat(py) {
        if (!imageLoaded || bigImage.sourceSize.height === 0) return 0
        var ratio = py / bigImage.sourceSize.height
        return maxLat - ratio * (maxLat - minLat)
    }
    
    // 统一的经纬度到屏幕坐标转换函数（支持固定参考尺寸）
    function lonLatToScreenPosition(lon, lat) {
        if (!imageLoaded || bigImage.sourceSize.width === 0) {
            return { x: 0, y: 0 }
        }
        
        // 1. 转换为原始图片像素坐标
        var pixelX = lonToPixelX(lon)
        var pixelY = latToPixelY(lat)
        
        // 2. 选择缩放比例：如果启用固定参考尺寸，使用固定比例；否则使用当前缩放
        var referenceScale = useFixedReference ? fixedReferenceScale : currentScale
        var scaledX = pixelX * referenceScale
        var scaledY = pixelY * referenceScale
        
        // 3. 减去Flickable的偏移，得到屏幕坐标
        var screenX = scaledX - flickable.contentX
        var screenY = scaledY - flickable.contentY
        
        console.log("坐标转换:", lon.toFixed(6), lat.toFixed(6), "->", screenX.toFixed(1), screenY.toFixed(1))
        console.log("- 使用参考缩放:", referenceScale, "(固定参考:", useFixedReference, ")")
        
        return { x: screenX, y: screenY }
    }
    
    // 屏幕坐标转经纬度（用于点击事件，支持固定参考尺寸）
    function screenPositionToLonLat(screenX, screenY) {
        if (!imageLoaded || bigImage.sourceSize.width === 0) {
            return { lon: 0, lat: 0 }
        }
        
        console.log("=== 坐标转换调试 ===")
        console.log("输入屏幕坐标:", screenX.toFixed(2), screenY.toFixed(2))
        console.log("Flickable偏移:", flickable.contentX.toFixed(2), flickable.contentY.toFixed(2))
        console.log("当前缩放比例:", currentScale.toFixed(4))
        console.log("固定参考缩放:", fixedReferenceScale.toFixed(4), "(启用:", useFixedReference, ")")
        console.log("图片原始尺寸:", bigImage.sourceSize.width, "x", bigImage.sourceSize.height)
        
        // 1. 加上Flickable的偏移，得到内容坐标
        var contentX = screenX + flickable.contentX
        var contentY = screenY + flickable.contentY
        console.log("内容坐标:", contentX.toFixed(2), contentY.toFixed(2))
        
        // 2. 选择缩放比例：如果启用固定参考尺寸，使用固定比例；否则使用当前缩放
        var referenceScale = useFixedReference ? fixedReferenceScale : currentScale
        var pixelX = contentX / referenceScale
        var pixelY = contentY / referenceScale
        console.log("原始图片坐标:", pixelX.toFixed(2), pixelY.toFixed(2), "(使用参考缩放:", referenceScale.toFixed(4), ")")
        
        // 3. 转换为经纬度
        var lon = pixelXToLon(pixelX)
        var lat = pixelYToLat(pixelY)
        console.log("最终经纬度:", lon.toFixed(8), lat.toFixed(8))
        console.log("地图范围检查:")
        console.log("- 经度范围:", minLon.toFixed(8), "到", maxLon.toFixed(8))
        console.log("- 纬度范围:", minLat.toFixed(8), "到", maxLat.toFixed(8))
        console.log("- 经度是否在范围内:", lon >= minLon && lon <= maxLon)
        console.log("- 纬度是否在范围内:", lat >= minLat && lat <= maxLat)
        console.log("==================")
        
        return { lon: lon, lat: lat }
    }
    
    // 更新中心位置
    function updateCenterLocation() {
        if (!imageLoaded) return
        
        var centerX = (flickable.contentX + flickable.width / 2) / currentScale
        var centerY = (flickable.contentY + flickable.height / 2) / currentScale
        
        var lon = pixelXToLon(centerX)
        var lat = pixelYToLat(centerY)
        
        locationChanged(lon, lat)
    }
    
    // 监听currentScale变化，确保Flickable内容大小与缩放同步
    onCurrentScaleChanged: {
        console.log("缩放比例变化:", currentScale)
        if (bigImage.status === Image.Ready && bigImage.sourceSize.width > 0) {
            // 使用sourceSize而不是width/height，避免Transform影响
            flickable.contentWidth = bigImage.sourceSize.width * currentScale
            flickable.contentHeight = bigImage.sourceSize.height * currentScale
            console.log("更新Flickable内容大小:", flickable.contentWidth, "x", flickable.contentHeight)
            
            // 夹紧偏移，避免越界导致坐标计算错误
            clampFlickableOffsets()
            
            // 强制重绘Canvas
            if (pathCanvas) {
                pathCanvas.requestPaint()
            }
            
            // 发送缩放变化信号
            scaleChanged(currentScale)
        }
    }
    
    // 加载地图
    function loadMap() {
        console.log("开始加载地图:", imagePath)
        
        // 重置加载状态
        imageLoaded = false
        imageLoading = true
        
        // 清除旧图并重新加载（使用 Qt.callLater 确保清除生效）
        bigImage.source = ""
        Qt.callLater(function() {
            bigImage.source = imagePath
        })
    }
    
    // 自动适应窗口
    function autoFitToWindow() {
        if (bigImage.sourceSize.width > 0 && bigImage.sourceSize.height > 0) {
            var scaleW = flickable.width / bigImage.sourceSize.width
            var scaleH = flickable.height / bigImage.sourceSize.height
            currentScale = Math.min(scaleW, scaleH, 1.0)
            console.log("自动适应窗口，缩放比例:", currentScale)
            
            // 确保Flickable内容大小与缩放同步（使用sourceSize）
            flickable.contentWidth = bigImage.sourceSize.width * currentScale
            flickable.contentHeight = bigImage.sourceSize.height * currentScale
            clampFlickableOffsets()
        }
    }
    
    // 重置视图
    function resetView() {
        currentScale = 1.0
        flickable.contentWidth = bigImage.sourceSize.width * currentScale
        flickable.contentHeight = bigImage.sourceSize.height * currentScale
        flickable.contentX = 0
        flickable.contentY = 0
        clampFlickableOffsets()
        console.log("视图已重置")
    }
    
    // 放大
    function zoomIn(delta) {
        var oldScale = currentScale
        currentScale = Math.min(maxScale, currentScale + delta)
        console.log("放大:", oldScale, "->", currentScale)
        // 更新Flickable的内容大小（使用sourceSize）
        flickable.contentWidth = bigImage.sourceSize.width * currentScale
        flickable.contentHeight = bigImage.sourceSize.height * currentScale
        clampFlickableOffsets()
    }
    
    // 缩小
    function zoomOut(delta) {
        var oldScale = currentScale
        currentScale = Math.max(minScale, currentScale - delta)
        console.log("缩小:", oldScale, "->", currentScale)
        // 更新Flickable的内容大小（使用sourceSize）
        flickable.contentWidth = bigImage.sourceSize.width * currentScale
        flickable.contentHeight = bigImage.sourceSize.height * currentScale
        clampFlickableOffsets()
    }
    
    // 设置地图中心点
    function setMapCenter(lon, lat, zoom) {
        if (!imageLoaded) {
            console.warn("地图未加载，无法设置中心点")
            return
        }
        
        var px = lonToPixelX(lon)
        var py = latToPixelY(lat)
        
        flickable.contentX = px * currentScale - flickable.width / 2
        flickable.contentY = py * currentScale - flickable.height / 2
        
        console.log("设置地图中心:", lon, lat)
    }
    
    // 设置缩放级别
    function setScale(scale) {
        if (scale >= minScale && scale <= maxScale) {
            var oldScale = currentScale
            currentScale = scale
            console.log("设置缩放级别:", oldScale, "->", currentScale)
            // 更新Flickable的内容大小（使用sourceSize）
            flickable.contentWidth = bigImage.sourceSize.width * currentScale
            flickable.contentHeight = bigImage.sourceSize.height * currentScale
            clampFlickableOffsets()
        } else {
            console.warn("缩放级别超出范围:", scale, "范围:", minScale, "-", maxScale)
        }
    }
    
    // 设置固定参考尺寸（解决缩放导致路径偏移问题）
    function setFixedReferenceScale(scale) {
        fixedReferenceScale = scale
        console.log("设置固定参考缩放比例:", fixedReferenceScale)
        
        // 强制重绘Canvas
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
    }
    
    // 启用/禁用固定参考尺寸机制
    function setUseFixedReference(enabled) {
        useFixedReference = enabled
        console.log("固定参考尺寸机制:", enabled ? "启用" : "禁用")
        
        // 强制重绘Canvas
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
    }
    
    // 添加标记点
    function addMarker(lon, lat, title, content) {
        if (lon < minLon || lon > maxLon || lat < minLat || lat > maxLat) {
            console.warn("标记点超出地图范围:", lon, lat)
            return
        }
        
        markersModel.append({
            lon: lon,
            lat: lat,
            title: title || "",
            content: content || "",
            color: "#e74c3c"
        })
        
        console.log("已添加标记点:", lon, lat, title)
    }
    
    // 清除所有标记
    function clearMarkers() {
        markersModel.clear()
        console.log("已清除所有标记点")
    }
    
    // 获取当前位置
    function getCurrentLocation() {
        if (!imageLoaded) {
            return { lon: 0, lat: 0 }
        }
        
        var centerX = (flickable.contentX + flickable.width / 2) / currentScale
        var centerY = (flickable.contentY + flickable.height / 2) / currentScale
        
        return {
            lon: pixelXToLon(centerX),
            lat: pixelYToLat(centerY)
        }
    }
    
    // ==================== 路径规划相关函数 ====================
    
    // 添加路径点
    function addPathPoint(lon, lat) {
        console.log("addPathPoint 被调用 - 参数:", lon, lat)
        console.log("地图范围检查 - minLon:", minLon, "maxLon:", maxLon, "minLat:", minLat, "maxLat:", maxLat)
        
        // 检查坐标是否在地图范围内（使用更大的容差值0.01度，约1公里）
        var tolerance = 0.01
        var lonInRange = (lon >= minLon - tolerance) && (lon <= maxLon + tolerance)
        var latInRange = (lat >= minLat - tolerance) && (lat <= maxLat + tolerance)
        
        if (!lonInRange || !latInRange) {
            console.warn("路径点超出地图范围:", lon, lat)
            console.warn("- 经度检查:", lon, "范围:", minLon, "-", maxLon, "是否在范围:", lonInRange)
            console.warn("- 纬度检查:", lat, "范围:", minLat, "-", maxLat, "是否在范围:", latInRange)
            // 尝试修正坐标到范围内
            lon = Math.max(minLon, Math.min(maxLon, lon))
            lat = Math.max(minLat, Math.min(maxLat, lat))
            console.log("修正后的坐标:", lon, lat)
        }
        
        pathPointsModel.append({
            lon: lon,
            lat: lat,
            timestamp: new Date().toISOString()
        })
        
        console.log("✅ 已添加路径点:", lon, lat, "总数:", pathPointsModel.count)
        console.log("路径点模型状态:", pathPointsModel.count, "个点")
        
        // 强制重绘Canvas
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
        
        pathPointAdded(lon, lat, pathPointsModel.count - 1)
        pathChanged()
        return true
    }
    
    // 删除指定索引的路径点
    function removePathPoint(index) {
        if (index >= 0 && index < pathPointsModel.count) {
            pathPointsModel.remove(index)
            console.log("已删除路径点，索引:", index)
            pathPointRemoved(index)
            pathChanged()
            return true
        }
        return false
    }
    
    // 删除最近的路径点
    function removeNearestPathPoint(lon, lat) {
        if (pathPointsModel.count === 0) return false
        
        var minDistance = Number.MAX_VALUE
        var nearestIndex = -1
        
        for (var i = 0; i < pathPointsModel.count; i++) {
            var point = pathPointsModel.get(i)
            var distance = Math.sqrt(
                Math.pow(point.lon - lon, 2) + Math.pow(point.lat - lat, 2)
            )
            
            if (distance < minDistance) {
                minDistance = distance
                nearestIndex = i
            }
        }
        
        // 如果距离小于0.001度（约100米），则删除
        if (minDistance < 0.001) {
            return removePathPoint(nearestIndex)
        }
        
        return false
    }
    
    // 清除所有路径点
    function clearPath() {
        console.log("clearPath 被调用")
        console.log("当前路径点模型状态:", pathPointsModel ? pathPointsModel.count : "undefined")
        
        if (!pathPointsModel) {
            console.error("路径点模型未初始化")
            return false
        }
        
        if (pathPointsModel.count === 0) {
            console.log("没有路径点可清除")
            return false
        }
        
        var pointCount = pathPointsModel.count
        var pathLength = calculatePathLength()
        
        console.log("清除路径确认:")
        console.log("- 路径点数:", pointCount)
        console.log("- 路径长度:", (pathLength / 1000).toFixed(2), "公里")
        
        // 清除路径点
        pathPointsModel.clear()
        
        // 退出编辑模式
        pathEditMode = false
        
        console.log("✅ 已清除所有路径点，共", pointCount, "个点")
        
        // 强制重绘Canvas
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
        
        // 触发路径变化信号
        pathChanged()
        
        return true
    }
    
    
    // 撤销最后一个路径点
    function undoLastPathPoint() {
        if (pathPointsModel.count > 0) {
            var lastIndex = pathPointsModel.count - 1
            var removedPoint = pathPointsModel.get(lastIndex)
            pathPointsModel.remove(lastIndex)
            
            console.log("撤销最后一个路径点:", removedPoint.lon.toFixed(6), removedPoint.lat.toFixed(6))
            pathChanged()
            return true
        }
        return false
    }
    
    
    // 获取路径点列表
    function getPathPoints() {
        var points = []
        for (var i = 0; i < pathPointsModel.count; i++) {
            var point = pathPointsModel.get(i)
            points.push({
                lon: point.lon,
                lat: point.lat,
                timestamp: point.timestamp
            })
        }
        return points
    }
    
    // 设置路径点列表
    function setPathPoints(points) {
        clearPath()
        for (var i = 0; i < points.length; i++) {
            var point = points[i]
            addPathPoint(point.lon, point.lat)
        }
    }
    
    // 计算路径总长度（米）
    function calculatePathLength() {
        if (pathPointsModel.count < 2) return 0
        
        var totalLength = 0
        for (var i = 0; i < pathPointsModel.count - 1; i++) {
            var point1 = pathPointsModel.get(i)
            var point2 = pathPointsModel.get(i + 1)
            
            // 使用Haversine公式计算距离
            var R = 6371000 // 地球半径（米）
            var dLat = (point2.lat - point1.lat) * Math.PI / 180
            var dLon = (point2.lon - point1.lon) * Math.PI / 180
            var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                    Math.cos(point1.lat * Math.PI / 180) * Math.cos(point2.lat * Math.PI / 180) *
                    Math.sin(dLon/2) * Math.sin(dLon/2)
            var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
            totalLength += R * c
        }
        
        return totalLength
    }
    
    // ==================== 机器人位置相关函数 ====================
    
    
    // 更新机器人位置
    function updateRobotPosition(sn, lon, lat, status) {
        // 查找现有机器人
        for (var i = 0; i < robotPositionsModel.count; i++) {
            var robot = robotPositionsModel.get(i)
            if (robot.sn === sn) {
                robotPositionsModel.set(i, {
                    sn: sn,
                    lon: lon,
                    lat: lat,
                    timestamp: new Date().toISOString(),
                    status: status || "在线"
                })
                console.log("已更新机器人位置:", sn, lon, lat)
                
                // 强制重绘Canvas
                if (pathCanvas) {
                    pathCanvas.requestPaint()
                }
                return true
            }
        }
        
        // 如果没找到，添加新的机器人位置
        robotPositionsModel.append({
            sn: sn,
            lon: lon,
            lat: lat,
            timestamp: new Date().toISOString(),
            status: status || "在线"
        })
        
        console.log("已添加机器人位置:", sn, lon, lat)
        
        // 强制重绘Canvas
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
        return true
    }
    
    
    // 获取机器人位置列表
    function getRobotPositions() {
        var robots = []
        for (var i = 0; i < robotPositionsModel.count; i++) {
            var robot = robotPositionsModel.get(i)
            robots.push({
                sn: robot.sn,
                lon: robot.lon,
                lat: robot.lat,
                timestamp: robot.timestamp,
                status: robot.status
            })
        }
        return robots
    }
    
    // ==================== 路径规划模式控制 ====================
    
    // 启用路径编辑模式
    function enablePathEditMode() {
        pathEditMode = true
        console.log("已启用路径编辑模式")
    }
    
    
    // 切换路径编辑模式
    function togglePathEditMode() {
        pathEditMode = !pathEditMode
        console.log("路径编辑模式:", pathEditMode ? "启用" : "禁用")
    }
    
    
    // ==================== 路径保存和加载功能 ====================
    
    
    
    // 导出路径为KML格式（Google Earth兼容）
    function exportPathToKML() {
        if (pathPointsModel.count === 0) {
            console.warn("没有路径点可导出")
            return ""
        }
        
        var kmlContent = '<?xml version="1.0" encoding="UTF-8"?>\n'
        kmlContent += '<kml xmlns="http://www.opengis.net/kml/2.2">\n'
        kmlContent += '  <Document>\n'
        kmlContent += '    <name>作业路径</name>\n'
        kmlContent += '    <description>甘蔗农机作业路径</description>\n'
        kmlContent += '    <Placemark>\n'
        kmlContent += '      <name>路径线</name>\n'
        kmlContent += '      <LineString>\n'
        kmlContent += '        <coordinates>\n'
        
        for (var i = 0; i < pathPointsModel.count; i++) {
            var point = pathPointsModel.get(i)
            kmlContent += '          ' + point.lon + ',' + point.lat + ',0\n'
        }
        
        kmlContent += '        </coordinates>\n'
        kmlContent += '      </LineString>\n'
        kmlContent += '      <Style>\n'
        kmlContent += '        <LineStyle>\n'
        kmlContent += '          <color>ff0000ff</color>\n'
        kmlContent += '          <width>3</width>\n'
        kmlContent += '        </LineStyle>\n'
        kmlContent += '      </Style>\n'
        kmlContent += '    </Placemark>\n'
        
        // 添加路径点
        for (var j = 0; j < pathPointsModel.count; j++) {
            var pathPoint = pathPointsModel.get(j)
            kmlContent += '    <Placemark>\n'
            kmlContent += '      <name>路径点 ' + (j + 1) + '</name>\n'
            kmlContent += '      <Point>\n'
            kmlContent += '        <coordinates>' + pathPoint.lon + ',' + pathPoint.lat + ',0</coordinates>\n'
            kmlContent += '      </Point>\n'
            kmlContent += '    </Placemark>\n'
        }
        
        kmlContent += '  </Document>\n'
        kmlContent += '</kml>\n'
        
        console.log("已生成KML内容，长度:", kmlContent.length)
        return kmlContent
    }
    
    // 导入路径从KML格式
    function importPathFromKML(kmlContent) {
        console.log("导入KML路径，内容长度:", kmlContent.length)
        
        // 简单的KML解析（实际项目中应该使用更完善的XML解析器）
        var coordinatesMatch = kmlContent.match(/<coordinates>([\s\S]*?)<\/coordinates>/)
        if (coordinatesMatch) {
            var coordinatesText = coordinatesMatch[1]
            var lines = coordinatesText.trim().split('\n')
            var points = []
            
            for (var i = 0; i < lines.length; i++) {
                var line = lines[i].trim()
                if (line) {
                    var parts = line.split(',')
                    if (parts.length >= 2) {
                        var lon = parseFloat(parts[0])
                        var lat = parseFloat(parts[1])
                        if (!isNaN(lon) && !isNaN(lat)) {
                            points.push({ lon: lon, lat: lat })
                        }
                    }
                }
            }
            
            if (points.length > 0) {
                setPathPoints(points)
                console.log("已导入KML路径，包含", points.length, "个点")
                return true
            }
        }
        
        console.warn("KML解析失败")
        return false
    }
    
    // 生成路径统计信息
    function getPathStatistics() {
        var stats = {
            pointCount: pathPointsModel.count,
            totalLength: calculatePathLength(),
            averageSegmentLength: 0,
            minSegmentLength: Number.MAX_VALUE,
            maxSegmentLength: 0,
            bounds: {
                minLon: Number.MAX_VALUE,
                maxLon: Number.MIN_VALUE,
                minLat: Number.MAX_VALUE,
                maxLat: Number.MIN_VALUE
            }
        }
        
        if (pathPointsModel.count > 1) {
            stats.averageSegmentLength = stats.totalLength / (pathPointsModel.count - 1)
            
            for (var i = 0; i < pathPointsModel.count - 1; i++) {
                var point1 = pathPointsModel.get(i)
                var point2 = pathPointsModel.get(i + 1)
                
                // 计算段长度
                var R = 6371000
                var dLat = (point2.lat - point1.lat) * Math.PI / 180
                var dLon = (point2.lon - point1.lon) * Math.PI / 180
                var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                        Math.cos(point1.lat * Math.PI / 180) * Math.cos(point2.lat * Math.PI / 180) *
                        Math.sin(dLon/2) * Math.sin(dLon/2)
                var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
                var segmentLength = R * c
                
                if (segmentLength < stats.minSegmentLength) stats.minSegmentLength = segmentLength
                if (segmentLength > stats.maxSegmentLength) stats.maxSegmentLength = segmentLength
                
                // 更新边界
                if (point1.lon < stats.bounds.minLon) stats.bounds.minLon = point1.lon
                if (point1.lon > stats.bounds.maxLon) stats.bounds.maxLon = point1.lon
                if (point1.lat < stats.bounds.minLat) stats.bounds.minLat = point1.lat
                if (point1.lat > stats.bounds.maxLat) stats.bounds.maxLat = point1.lat
            }
            
            // 处理最后一个点
            var lastPoint = pathPointsModel.get(pathPointsModel.count - 1)
            if (lastPoint.lon < stats.bounds.minLon) stats.bounds.minLon = lastPoint.lon
            if (lastPoint.lon > stats.bounds.maxLon) stats.bounds.maxLon = lastPoint.lon
            if (lastPoint.lat < stats.bounds.minLat) stats.bounds.minLat = lastPoint.lat
            if (lastPoint.lat > stats.bounds.maxLat) stats.bounds.maxLat = lastPoint.lat
        }
        
        return stats
    }
    
    // 工具函数：夹紧Flickable偏移，避免越界
    function clampFlickableOffsets() {
        var maxCX = Math.max(0, flickable.contentWidth - flickable.width)
        var maxCY = Math.max(0, flickable.contentHeight - flickable.height)
        
        var oldX = flickable.contentX
        var oldY = flickable.contentY
        
        if (flickable.contentX < 0) flickable.contentX = 0
        if (flickable.contentY < 0) flickable.contentY = 0
        if (flickable.contentX > maxCX) flickable.contentX = maxCX
        if (flickable.contentY > maxCY) flickable.contentY = maxCY
        
        // 调试信息
        if (oldX !== flickable.contentX || oldY !== flickable.contentY) {
            console.log("夹紧Flickable偏移:")
            console.log("- 内容尺寸:", flickable.contentWidth.toFixed(1), "x", flickable.contentHeight.toFixed(1))
            console.log("- 视口尺寸:", flickable.width.toFixed(1), "x", flickable.height.toFixed(1))
            console.log("- 最大偏移:", maxCX.toFixed(1), "x", maxCY.toFixed(1))
            console.log("- 偏移变化:", oldX.toFixed(1), oldY.toFixed(1), "->", flickable.contentX.toFixed(1), flickable.contentY.toFixed(1))
        }
    }
    
    // ==================== 农田规划功能 ====================
    
    // 添加农田规划点
    function addFieldPoint(lon, lat) {
        // 使用更大的容差值
        var tolerance = 0.01
        var lonInRange = (lon >= minLon - tolerance) && (lon <= maxLon + tolerance)
        var latInRange = (lat >= minLat - tolerance) && (lat <= maxLat + tolerance)
        
        if (!lonInRange || !latInRange) {
            console.warn("农田点超出地图范围，自动修正:", lon, lat)
            lon = Math.max(minLon, Math.min(maxLon, lon))
            lat = Math.max(minLat, Math.min(maxLat, lat))
        }
        
        fieldPointsModel.append({lon: lon, lat: lat})
        fieldPlanSaved = false
        console.log("添加农田规划点:", lon.toFixed(6), lat.toFixed(6), "总数:", fieldPointsModel.count)
        
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
    }
    
    // 清除农田规划
    function clearFieldPlan() {
        fieldPointsModel.clear()
        fieldPlanMode = false
        fieldPlanSaved = false
        console.log("清除农田规划")
        
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
    }
    
    // 切换农田规划模式
    function toggleFieldPlanMode() {
        fieldPlanMode = !fieldPlanMode
        if (!fieldPlanMode) {
            console.log("退出农田规划模式")
        } else {
            console.log("进入农田规划模式")
            if (fieldPointsModel.count >= 3) {
                fieldPlanSaved = false
            }
        }
    }
    
    // 标记农田为已保存状态
    function markFieldPlanAsSaved() {
        fieldPlanSaved = true
        console.log("农田规划已标记为已保存")
        
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
    }
    
    // 计算农田面积（亩）
    function calculateFieldArea() {
        if (fieldPointsModel.count < 3) {
            return 0
        }
        
        var R = 63710 // 地球半径（米）
        var area = 0
        
        for (var i = 0; i < fieldPointsModel.count; i++) {
            var p1 = fieldPointsModel.get(i)
            var p2 = fieldPointsModel.get((i + 1) % fieldPointsModel.count)
            
            area += (p2.lon - p1.lon) * (2 + Math.sin(p1.lat * Math.PI / 180) + Math.sin(p2.lat * Math.PI / 180))
        }
        
        area = Math.abs(area * R * R / 2)
        var mu = area * 0.0015
        
        return mu
    }
    
    // 加载农田规划
    function loadFieldPlan(points) {
        if (!points || points.length < 3) {
            console.warn("无法加载：农田点数不足3个")
            return false
        }
        
        fieldPointsModel.clear()
        for (var i = 0; i < points.length; i++) {
            fieldPointsModel.append({
                lon: points[i].lon,
                lat: points[i].lat
            })
        }
        
        fieldPlanSaved = true
        
        console.log("加载农田规划成功，点数:", fieldPointsModel.count)
        
        if (pathCanvas) {
            pathCanvas.requestPaint()
        }
        return true
    }
    
    // 获取农田规划点数据
    function getFieldPlanData() {
        var points = []
        for (var i = 0; i < fieldPointsModel.count; i++) {
            var point = fieldPointsModel.get(i)
            points.push({
                lon: point.lon,
                lat: point.lat
            })
        }
        return points
    }
}

